package com.github.baichuan.application.scaffold.jpa.authorization;


import com.github.baichuan.application.scaffold.domain.application.Application;
import com.github.baichuan.application.scaffold.domain.authorization.Role;
import com.github.baichuan.application.scaffold.domain.organization.Tenant;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;

import java.util.List;
import java.util.Optional;

@Repository
public interface RoleRepository extends JpaRepository<Role, String>, JpaSpecificationExecutor<Role> {

    @Query(value = "select role from Role as role where role.application.id=:applicationId and role.tenant=:tenant and name=:name")
    Optional<Role> find(@Param("applicationId") String applicationId, @Param("tenant") Tenant tenant, @Param("name") String name);

    @Query("select role from Role role where role.application=:application and role.id=:id")
    Optional<Role> find(@Param("application") Application application, @Param("id") String id);

    @Query(value = "select role.* from role \n" +
            "join application on role.application_id=application.id\n" +
            "where application.code=:application \n" +
            "  and (org_uid=:orgUid Or exists (\n" +
            "  SELECT role_id FROM application_member am JOIN application_member_privilege amp ON am.id=amp.application_member_id WHERE org_uid=:orgUid and amp.role_id=role.id))", nativeQuery = true)
    List<Role> getAvailables(@Param("application") String application, @Param("orgUid") String orgUid);

//    List<Role> getByTenant(Tenant tenant);

    List<Role> findByIdIn(List<String> roles);

    List<Role> findByApplication(Application application);

    @Query(value = "SELECT COUNT(*) FROM application_member JOIN application_member_privilege privilege ON application_member.id=privilege.application_member_id WHERE privilege.role_id=:roleId", nativeQuery = true)
    int countMembers(@Param("roleId") String roleId);

//    @Query(value = "SELECT resource_id FROM role_privilege WHERE role_id=:roleId", nativeQuery = true)
//    List<String> getResources(@Param("roleId") short roleId);

    /**
     * 创建默认管理员时授权
     */
    @Modifying
    @Query(value = "INSERT INTO role_privilege (role_id, resource_id) SELECT :roleId, id FROM resource WHERE application_id=:applicationId", nativeQuery = true)
    void adminAuthorize(@Param("applicationId") String applicationId, @Param("roleId") String roleId);

}
